#include "medianfilter.h"

MedianFilter::MedianFilter(){
    width = 3;
    height = 3;

}


void MedianFilter::filter(QImage *image){

    QImage* imageCopy = new QImage(*image);

    int** matriceR;
    matriceR = new int*[3];
    for(int i=0;i<3;i++){
      matriceR[i] = new int[3];
    }

    int** matriceG;
    matriceG = new int*[3];
    for(int i=0;i<3;i++){
      matriceG[i] = new int[3];
    }

    int** matriceB;
    matriceB = new int*[3];
    for(int i=0;i<3;i++){
      matriceB[i] = new int[3];
    }

//Attention, je n'ai pas pris les bords en compte!! A voir!!!

    for(int x=1;x<imageCopy->width()-1;x++){
        for(int y=1;y<imageCopy->height()-1;y++){
            //red component
            matriceR[0][0] = qRed(imageCopy->pixel(x-1,y-1)) ;   matriceR[0][1] = qRed(imageCopy->pixel(x,y-1));   matriceR[0][2] = qRed(imageCopy->pixel(x+1,y-1));
            matriceR[1][0] = qRed(imageCopy->pixel(x-1,y));   matriceR[1][1] = qRed(imageCopy->pixel(x,y)) ;  matriceR[1][2] =qRed( imageCopy->pixel(x+1,y));
            matriceR[2][0] = qRed(imageCopy->pixel(x-1,y+1));   matriceR[2][1] = qRed(imageCopy->pixel(x,y+1));   matriceR[2][2]= qRed(imageCopy->pixel(x+1,y+1));
            int medianeR = Mediantri(matriceR);

            //green component
            matriceG[0][0] = qGreen(imageCopy->pixel(x-1,y-1)) ;   matriceG[0][1] = qGreen(imageCopy->pixel(x,y-1));   matriceG[0][2] = qGreen(imageCopy->pixel(x+1,y-1));
            matriceG[1][0] = qGreen(imageCopy->pixel(x-1,y));   matriceG[1][1] = qGreen(imageCopy->pixel(x,y)) ;  matriceG[1][2] =qGreen( imageCopy->pixel(x+1,y));
            matriceG[2][0] = qGreen(imageCopy->pixel(x-1,y+1));   matriceG[2][1] = qGreen(imageCopy->pixel(x,y+1));   matriceG[2][2]= qGreen(imageCopy->pixel(x+1,y+1));
            int medianeG = Mediantri(matriceG);

            //blue component
            matriceB[0][0] = qBlue(imageCopy->pixel(x-1,y-1)) ;   matriceB[0][1] = qBlue(imageCopy->pixel(x,y-1));   matriceB[0][2] = qBlue(imageCopy->pixel(x+1,y-1));
            matriceB[1][0] = qBlue(imageCopy->pixel(x-1,y));   matriceB[1][1] = qBlue(imageCopy->pixel(x,y)) ;  matriceB[1][2] =qBlue( imageCopy->pixel(x+1,y));
            matriceB[2][0] = qBlue(imageCopy->pixel(x-1,y+1));   matriceB[2][1] = qBlue(imageCopy->pixel(x,y+1));   matriceB[2][2]= qBlue(imageCopy->pixel(x+1,y+1));
            int medianeB = Mediantri(matriceB);

            image->setPixel(x,y,qRgb(medianeR,medianeG,medianeB));

        }
    }


}

int MedianFilter::Mediantri(int** matrice){

//ici, la matrice reprsente le carr 3*3 du voisinage du pixel en cours.


    int* tab = new int[3];
    int k=0;
    //pour chaque ligne de la matrice je fais un tri
    for(int j=0;j<width;j++){
        for(int i=0; i<height;i++){
            tab[i]= matrice[j][i];
        }

        tri(tab);

        for(int k=0;k<3;k++){
            matrice[j][k] = tab[k];
        }
    }

    //pour chaque colonne de la matrice je fais un tri
    for(int i=0;i<height;i++){
        for(int j=0; j<width;j++){
            tab[j]= matrice[j][i];
        }

        tri(tab);

        for(int k=0;k<3;k++){
            matrice[k][i] = tab[k];
        }
    }
    //je trie enfin la diagonale secondaire (du bas gauche vers haut droit)
    tab[0]=matrice[2][0];
    tab[1]=matrice[1][1];
    tab[2]=matrice[0][2];
    tri(tab);

    return  matrice[1][1];


}


void MedianFilter::tri(int* tab){

    for(int i=0;i<2;i++){
        for(int j=i+1;j<3;j++){
            if(tab[i]>tab[j]){
                int tmp = tab[j];
                tab[j] = tab[i];
                tab[i] = tmp;
            }
        }
    }

}
